package com.file;

import java.io.File;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;

public class EdbCKEncoding {
	static final int UCS4_TAB = 0x00000009;
	static final int UCS4_NL = 0x0000000a;
	static final int UCS4_CR = 0x0000000d;
	static final int UCS4_SPACE = 0x00000020;
	static final int UCS4_ASCII_upperbound = 0x0000007f;
	static final String[] charset = { "ISO2022JP", "EUC-JP", "SJIS",
			"MS932", "UTF-8", "UTF-16", "UTF-16LE", "UTF-16BE", "JIS0201", };
	String enc = "", decbody = "";

	public EdbCKEncoding(File file) {
		// String charset = System.getProperty("file.encoding");
		// String linesep = System.getProperty("line.separator");
		// System.out.println("charset: "+charset);
		// System.out.println("linesep: "+linesep);
		byte[] body = getByte(file);
		enc = getEncoding(body);
	}

	public EdbCKEncoding(byte[] body) {
		enc = getEncoding(body);
	}

	public String getEncoding() {
		return enc;
	}

	public String getString() {
		return decbody;
	}

	byte[] getByte(File file) {
		byte[] body = null;
		try {
			FileInputStream fin = new FileInputStream(file.getPath());
			byte[] buffer = new byte[8192];
			int rsize = fin.read(buffer);
			if (rsize < 0)
				return body;
			body = new byte[rsize];
			for (int i = 0; i < rsize; i++)
				body[i] = buffer[i];
			fin.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return body;
	}

	boolean compare_array(byte[] diff1, byte[] diff2) {
		int i, len = (diff1.length > diff2.length) ? diff2.length
				: diff1.length;
		for (i = 0; i < len; i++) {
			if (diff1[i] != diff2[i])
				break;
		}
		return (i == len) ? true : false;
	}

	boolean isEnglish(int c) {
		// Basic Latin
		if (UCS4_SPACE <= c && c < UCS4_ASCII_upperbound)
			return true;
		// Latin-1Supplement / Latin Extended-A / Latin Extended-B
		if (0x000000a1 <= c && c <= 0x00000233 && c != 0x000000ad
				&& c != 0x00000221)
			return true;
		// Greek and Coptic
		if (0x00000391 <= c && c <= 0x000003f6 && c != 0x000003a2
				&& c != 0x000003cf)
			return true;
		// Letterlike Symbols
		if (0x00002100 <= c && c <= 0x0000214b && c != 0x0000213b
				&& c != 0x0000213c)
			return true;
		// Letterlike Symbols
		if ((0x00002190 <= c && c <= 0x00002193) || c == 0x000021d2
				|| c == 0x000021d4)
			return true;
		// Mathematical Operators
		if (0x00002200 <= c && c <= 0x000022ff)
			return true;
		return false;
	}

	boolean isAscii(byte[] body) {
		for (int i = 0; i < body.length; i++) {
			if (isEnglish(body[i]) || body[i] == UCS4_NL
					|| body[i] == UCS4_CR || body[i] == UCS4_TAB)
				;
			else
				return false;
		}
		return true;
	}

	String getEncoding(byte[] body) {
		if (body == null)
			return "null";
		if (isAscii(body)) {
			decbody = new String(body);
			return "ASCII";
		}
		for (int i = 0; i < charset.length; i++) {
			try {
				String str = new String(body);
				byte[] body2 = str.getBytes(charset[i]);
				if (compare_array(body, body2)) {
					ByteBuffer bb = ByteBuffer.wrap(body2);
					decbody = new String(Charset.forName(charset[i])
							.decode(bb).array());
					if (charset[i].equals("JIS0201"))
						return "null";
					return charset[i];
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		for (int i = 0; i < charset.length; i++) {
			try {
				String str = new String(body, charset[i]);
				byte[] body2 = str.getBytes(charset[i]);
				if (compare_array(body, body2)) {
					ByteBuffer bb = ByteBuffer.wrap(body2);
					decbody = new String(Charset.forName(charset[i])
							.decode(bb).array());
					if (charset[i].equals("JIS0201"))
						return "null";
					return charset[i];
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return "null";
	}
}
